﻿Option Strict On
Imports System.CodeDom
Imports System.CodeDom.Compiler
Imports Microsoft.VisualBasic
Imports System.Windows.Forms
Namespace NetScript
    'Creator - HF Tweety
    'Profile - http://www.hackforums.net/member.php?action=profile&uid=1234585
    'Website - www.codeineject.co.uk
    'Twitter - @Codeinject
    ''' <summary>
    ''' Net Script is a light weight application to run text files as .NET application or scripts
    ''' It transforms the language into a scripting language, making it as powerful and easy to use as Batch files or VB 
    ''' </summary>
    ''' <remarks>
    ''' </remarks>
    Module VisualBasic
        Sub Main()

            If Environment.GetCommandLineArgs().Length = 0 Then Environment.Exit(0)
            For Each Source As [String] In Environment.GetCommandLineArgs()
                If Source = Application.ExecutablePath Then Continue For
                If Not IO.File.Exists(Source) Then Continue For
                Source = IO.File.ReadAllText(Source)

                Using CodeProvider As New Microsoft.VisualBasic.VBCodeProvider
                    Dim Parameters As New CompilerParameters
                    Try
                        Parameters.TempFiles.KeepFiles = False
                        Parameters.GenerateExecutable = False
                        Parameters.GenerateInMemory = True
                        Parameters.ReferencedAssemblies.AddRange(RetrieveReference(Source))
                        Dim Result As CompilerResults = CodeProvider.CompileAssemblyFromSource(Parameters,
                                                                                               New [String](CType(Source, Char())))
                        If Not Result.Errors.Count = 0 Then
                            For Each r As CompilerError In Result.Errors
                                Debug.Print("At line " + CStr(r.Line) +
                                            Environment.NewLine +
                                            Environment.NewLine +
                                            r.ErrorText)
                                MessageBox.Show("At line " + CStr(r.Line) +
                                                Environment.NewLine +
                                                Environment.NewLine +
                                                r.ErrorText,
                                                "Error",
                                                MessageBoxButtons.OK,
                                                MessageBoxIcon.Error)
                            Next
                            Exit Sub
                        End If
                        Dim ASM As Object = Result.CompiledAssembly.CreateInstance(RetrieveNamespace(Source) +
                                                                                   New [String](CType(".", Char())) +
                                                                                   RetrieveClass(Source))
                        ASM.GetType().GetMethod("Main").Invoke(ASM, Nothing)
                        EraseModule(Parameters)
                    Catch ex As Exception
                        EraseModule(Parameters)
                        Debug.Print(ex.Message)
                        MessageBox.Show(ex.Message,
                                        "Error",
                                         MessageBoxButtons.OK,
                                         MessageBoxIcon.Error)
                        Environment.Exit(0)
                    End Try
                End Using
            Next
        End Sub
        <STAThread()> _
        Private Sub EraseModule(ByRef Obj As CompilerParameters)
            Try
                Obj.TempFiles.Delete()
            Catch ex As Exception
                Debug.WriteLine(ex.Message)
            End Try
        End Sub
        Private Function RetrieveReference(ByVal Source As [String]) As [String]()
            Dim RefList As New List(Of String)
            For Each Import As [String] In Source.ToLower.Split(CChar(Environment.NewLine))
                If Import.ToLower.Contains("imports ") Then
                    Import = Import.Split(CChar(" "))(1)
                    RefList.Add(Import + ".dll")
                End If
            Next
            Return RefList.ToArray()
        End Function
        Private Function RetrieveNamespace(ByVal Source As [String]) As [String]
            For Each Line As [String] In Source.ToLower.Split(CChar(Environment.NewLine))
                If Line.ToLower.Contains("namespace") Then
                    Return CStr(Line.Split(CChar(" "))(1).Chars(0)).ToUpper + Line.Split(CChar(" "))(1).Remove(0, 1)
                End If
            Next
            Return String.Empty
        End Function
        Private Function RetrieveClass(ByVal Source As [String]) As [String]
            For Each Line As [String] In Source.ToLower.Split(CChar(Environment.NewLine))
                If Line.ToLower.Contains("class") OrElse Line.ToLower.Contains("module") Then
                    Return CStr(Line.Split(CChar(" "))(1).Chars(0)).ToUpper + Line.Split(CChar(" "))(1).Remove(0, 1)
                End If
            Next
            Return String.Empty
        End Function
    End Module
End Namespace

